﻿#include "StdAfx.h"
#include "PackageFile.h"
#include "Compress.h"
#include <io.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <Shlwapi.h>
#include <zlib/zlib.h>
#include "md5.h"
using namespace SECRIET;

#define SEC_KEY_PARAM1	"*+!rjwe&oe2m0!4_yn2v"
#define SEC_KEY_PARAM2	"@#!web$jeofgr.,?i_32"
#define SEC_KEY_PARAM3	"/?>we68etofgr_)37kl,"
#define SEC_KEY_PARAM4	"<me[laierp0924-rkop"
#define SEC_KEY_PARAM5	"abcdefgjijklmnopqrs"
#define SEC_KEY_PARAM6	"tquvw1234567890!@#$"
#define SEC_KEY_PARAM7	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define SEC_KEY_SIZE	strlen(SEC_KEY_PARAM1)

#ifndef ENCRYPT
#define ENCRYPT0(x,xlen,KEY,BeginPlace,KeyLen)	if( (x)!=NULL ) \
		{ \
		\
			BYTE* t_pBuffer = (x); \
			for (UINT i = 0; i < (xlen); i++) \
			{ \
				*t_pBuffer ^= KEY[(i+BeginPlace)%KeyLen]; \
				t_pBuffer++; \
			} \
		}
#define ENCRYPT(x,xlen,KEY,BeginPlace,KeyLen)	if( (x)!=NULL ) \
		{ \
			BYTE* t_pBuffer = (x); \
			BYTE chKey = 0; \
			for (UINT i = 0; i < (xlen); i++) \
			{ \
				chKey = KEY[(i+BeginPlace)%KeyLen]; \
				if ( *t_pBuffer && *t_pBuffer != chKey ) \
					*t_pBuffer ^= chKey; \
				t_pBuffer++; \
			} \
		}
#endif

void	_tagPackageHeader_1_0::InitPassword()
{
	const char *p[7] = {SEC_KEY_PARAM1,SEC_KEY_PARAM2,SEC_KEY_PARAM3,SEC_KEY_PARAM4,SEC_KEY_PARAM5,SEC_KEY_PARAM6,SEC_KEY_PARAM7};

	for( int i=0 ;i<8; ++i )
	{
		for( int j=0; j<16; ++j )
		{
			secPassword[j][i] = p[ (i+j)%7 ][ (i*j)%18];
		}
	}
}

BOOL _FileIsExist(LPCTSTR DirName)
{
	if(DirName==NULL)
		return FALSE;
	DWORD dwAttr = ::GetFileAttributes(DirName);
	if (dwAttr == 0xFFFFFFFF)
		return FALSE;
	if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
		return FALSE;
	return TRUE;
}

std::string ConvertLower(const std::string& name)
{
	std::string ret;
	for(int i = 0; i < name.size() ; ++i)
		ret+= (char)tolower(name.at(i));
	return ret;
}

int gpCompress(char *pDst,UINT &lenDst,const char *pSrc,UINT lenSrc,int nCompressMethod)
{
	uLongf len = lenDst;
	int n = compress2((Bytef *)pDst,&len,(const Bytef *)pSrc,lenSrc,nCompressMethod);
	lenDst = len;
	return n;
}

int gpUncompress(char *pDst,UINT &lenDst,const char *pSrc,UINT lenSrc)
{
	uLongf len = lenDst;
	int n = uncompress((Bytef *)pDst,&len,(const Bytef *)pSrc,lenSrc);
	lenDst = len;
	return n;
}

CPackageFile::CPackageFile(void)
{
	m_pFuncCompress = NULL;
	m_pFuncUnCompress = NULL;
	m_hFile = -1;
	//m_hIndexFile = -1;
	Close();
	SetCompressFunc(gpCompress , gpUncompress);
}

CPackageFile::~CPackageFile(void)
{
	Close();
}


//-----------------------------------------------------------------------------------
// 确定文件是否打开
// 参数：
//		
//	返回值：
//		打开TRUE，否则返回FALSE
BOOL	CPackageFile::IsOpen()
{
	if(m_hFile == -1)
	{
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}

//-----------------------------------------------------------------------------------
// 返回包中文件个数
// 参数：
//
//	返回值：
//		失败返回-1， 成功返回文件个数
INT 	CPackageFile::GetFileCount()
{
	if(!IsOpen())
	{
		return -1;
	}

	int nCount = 0;
	for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
	{
		if( it->second->byModifyFlag != GL_FILE_STATE_MARK_DEL )
			nCount++;
	}
	return nCount;
}

//-----------------------------------------------------------------------------------
// 判断文件在包中是否存在
// 参数：
//		lpszFileName		文件名，不包含路径
//	返回值：
//		文件存在返回TRUE，否则返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::FileExist(LPCTSTR lpszFileName)
{
	FileIndexList::iterator it = m_PackFileIndex.find(strlwr( _strdup(lpszFileName)));
	if ( it != m_PackFileIndex.end() )
	{
		if( it->second->byModifyFlag == GL_FILE_STATE_NORMAL)
			return TRUE;
	}
	return FALSE;
}

ConFileIndex CPackageFile::GetFileIndex( LPCTSTR pFilename )
{
	FileIndexList::iterator it = m_PackFileIndex.find(strlwr( _strdup(pFilename)));
	return it;
}

BOOL	CPackageFile::IsSameFile( const PACKAGE_FILE_INFO &fInfo )
{
	if( !FileExist( fInfo.szFileName) )
		return FALSE;
	PACKAGE_FILE_INFO fLocalInfo;
	GetFileInfo( GetFileIndex(fInfo.szFileName), fLocalInfo );
	if( fLocalInfo.uAppendInfoLength != 0 )
	{
		int br = 0;
		++br;
	}
	BOOL b = (fInfo.uFileLength==fLocalInfo.uFileLength) && (fInfo.uAppendInfoLength==fLocalInfo.uAppendInfoLength);
	if( b )
		return memcmp( fLocalInfo.szBufferID, fInfo.szBufferID, 16 ) == 0;
	else
		return FALSE;
}

VOID	CPackageFile::EnableSecret( BOOL b)
{
	m_PackageHeader.dwSec = b;
}

//-----------------------------------------------------------------------------------
// 设置包的描述字符串
// 参数：
//		lpszTitle			包说明
//	返回值：
//		
//-----------------------------------------------------------------------------------
void CPackageFile::SetPackageTitle(LPCTSTR lpszTitle)
{
	if(m_bReadOpen)
	{
		return;
	}
	if(lpszTitle == NULL)
	{
		return;
	}
	ZeroMemory(m_PackageHeader.szPackageName, sizeof(m_PackageHeader.szPackageName));

	if(_strlen(lpszTitle) >= 127)
	{
		StrCpyN(m_PackageHeader.szPackageName,lpszTitle,127);
	}
	else
	{
		StrCpy(m_PackageHeader.szPackageName,lpszTitle);
	}

	if( _lseeki64(m_hFile, sizeof(CHAR) * 4, SEEK_SET) == -1)
	{
		return ;
	}

	Write(m_hFile, &m_PackageHeader.szPackageName, sizeof(m_PackageHeader.szPackageName));
}

//-----------------------------------------------------------------------------------
// 返回包的描述字符串
// 参数：
//		
//	返回值：
//		包说明
//-----------------------------------------------------------------------------------
LPCTSTR CPackageFile::GetPackageTitle()
{
	return m_PackageHeader.szPackageName;
}

void	 CPackageFile::SetPackageFileVersion( INT nVersion )
{
	m_PackageHeader.dwPackageFileVersion = nVersion;
}
INT		 CPackageFile::GetPackageFileVersion()
{
	return m_PackageHeader.dwPackageFileVersion;
}

void	 CPackageFile::SetPackageFilePreVersion(INT nVersion )
{
	m_PackageHeader.dwPackageFilePreVersion = nVersion;
}

INT		 CPackageFile::GetPackageFilePreVersion()
{
	return m_PackageHeader.dwPackageFilePreVersion;
}

void	 CPackageFile::SetPackageType( BYTE nType )
{
	m_PackageHeader.dwPackageFileType = nType;
}

BYTE	 CPackageFile::GetPackageType()
{
	return m_PackageHeader.dwPackageFileType;
}

void	CPackageFile::SavePackageHeaderToDisk()
{
	_lseeki64(m_hFile, 0, SEEK_SET);
	SavePackageHeader(m_hFile);
}
//-----------------------------------------------------------------------------------
//  功  能：检测当前版本是不是类支持的最新版本
//	返回值：
//		不是最新版返回TRUE，否则返回FALSE
//-----------------------------------------------------------------------------------
BOOL   CPackageFile::IsNeedUpdate()
{
	if(m_PackageHeader.dwPackageVersion > PACKAGE_VERSOIN)
	{
		return FALSE;
	}

	if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSOIN)
	{
		return FALSE;
	}
	return TRUE;

}
//-----------------------------------------------------------------------------------
//  功  能：如果当前版本不是类支持的最新版本则升级文件
//	返回值：
//		不用升级或升级成功返回TRUE，否则返回FALSE
//-----------------------------------------------------------------------------------
BOOL  CPackageFile::UpdatePackageFile()
{
	if(!IsNeedUpdate())
	{
		return TRUE;
	}

    //保存文件内容
	TCHAR szBackFile[MAX_PATH];
	TCHAR szPathName[MAX_PATH];
	TCHAR szIndexFile[MAX_PATH];

	StrCpy(szPathName, m_szPathName);

	ZeroMemory(szIndexFile, sizeof(szIndexFile));
	ZeroMemory(szBackFile, sizeof(szBackFile));
	StrCpy(szIndexFile, m_szPathName);
	StrCpy(szBackFile, m_szPathName);
	StrCat(szBackFile, _T(".bak"));
	StrCat(szIndexFile, _T(".idx"));

	if(!Save(szBackFile))
	{
        return FALSE;
	}
	Close();

	if(_FileIsExist(szIndexFile))
	{
		if(!DeleteFile(szIndexFile))
		{
			return Open(szPathName, GL_FILE_OPEN_WRITE);
		}
	}

	if(DeleteFile(szPathName))
	{
		__rename(szBackFile, szPathName);
	}
	return Open(szPathName, GL_FILE_OPEN_WRITE);
}



//-----------------------------------------------------------------------------------
// 打开包文件
// 参数：
//		hFile			  已经打开的文件句柄
//	返回值：
//		成功回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Open(INT hFile)
{
	if(hFile == -1)
	{
		return FALSE;
	}
	m_hFile = hFile;
	//m_hIndexFile = -1;
	if( _filelength(hFile) == 0)
	{
		m_PackageHeader.dbModifyTime = GetSystemTime();
		m_PackageHeader.InitPassword();
		m_PackageHeader.dwFileState = 0;
		m_PackageHeader.dwSec = 1;
		m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
		int offset = (BYTE*)&m_PackageHeader.dwFileState-(BYTE*)&m_PackageHeader;
		return SavePackageHeader();
	}
	//验证文件有效性
	m_hFile = hFile;

	int sizePKH = 936;
	int sizePKH_C = sizeof(m_PackageHeader);
	UINT uPackHeaderSize = sizeof(m_PackageHeader) - sizeof(double);

	///1.0版本的空文件长度
	if( _read(m_hFile, &m_PackageHeader, uPackHeaderSize) < SAVE_FLAG_POSITION_1_0 )
	{
		Close();
		return FALSE;
	}

	ULONG *pL = (ULONG *)&m_PackageHeader;
	ULONG l1 = pL[0];

	if(StrCmp(m_PackageHeader.szPackIdentifier,_T(FILE_PACKET_IDENTIFY)) != 0)
	{
		Close();
		return FALSE;
	}

	//检查版号1.0
	if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
	{
		//1.0版本没有这个字椴
		m_PackageHeader.dbModifyTime = GetSystemTime();
		//对于以前版本的文件将以只读方式打开

		memset( &m_PackageHeader.dwReserved, 0 ,sizeof(m_PackageHeader.dwReserved) );
		_lseeki64( hFile, SAVE_FLAG_POSITION_1_0, SEEK_SET );	///对于以前版本，设置到正确的初始位置
//		m_bReadOpen = TRUE;
	}
	//当前最新版本
	else if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_2)
	{
		//if( sizeof(DWORD)*128 != _read(hFile, &m_PackageHeader.dwReserved, sizeof(DWORD)*128) )
		//{
		//	return false;
		//}
		int x = 0;
	}
	else
	{
		Close();
		return FALSE;
	}

	if( sizeof(BYTE) != _read(hFile, &m_bySaveFlags, sizeof(BYTE) ))
	{
		return TRUE;
	}
	
	if(m_bySaveFlags == 1)
	{
		//TRACE("\n发现包数据写入错，尝试恢复\n");
	}
	if(!CreateFileIndex())
	{
		return FALSE;
	}
	
	return TRUE;
}


BOOL	CPackageFile::DelAllFile()
{
	for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
	{		
		delete it->second;
	}
	m_PackFileIndex.clear();
	_chsize_s(m_hFile, 0 );
	_lseeki64(m_hFile, 0, SEEK_SET);
	m_PackageHeader.dwDelNumberInBytes = 0;
	SavePackageHeader(m_hFile);
	BeginSave( m_hFile );
//	Save(m_szPathName);
	EndSave( m_hFile );
	return TRUE;
}

//-----------------------------------------------------------------------------------
// 从索引文件读入文件索引表
// 参数：
//
//	返回值：
//
//-----------------------------------------------------------------------------------
/*
BOOL CPackageFile::LoadFileIndex(INT hFile)
{
	//不再使用索引文件
	return FALSE;

	if(hFile == -1)
	{
		return FALSE;
	}

	UINT uFileLen = _filelength(hFile);
	if(uFileLen == 0)
	{
		return FALSE;
	}

	BYTE* pBuf = Read(hFile, uFileLen);
	if(pBuf == NULL)
	{
		return FALSE;
	}

	BYTE* pRead = pBuf;

	DWORD* pVersion = (DWORD*)pBuf;
	if(uFileLen < (UINT)sizeof(DWORD) || *pVersion != PACKAGE_VERSOIN)
	{
		delete[] pBuf;
		return FALSE;
	}
    
	pRead += (int)sizeof(DWORD);
	uFileLen -= (UINT)sizeof(DWORD);

	double* pModifyTime = (double*)pRead;
	if(uFileLen < (UINT)sizeof(double) || *pModifyTime != m_PackageHeader.dbModifyTime)
	{
		delete[] pBuf;
		return FALSE;
	}

	pRead += (int)sizeof(double);
	uFileLen -= (UINT)sizeof(double);

	if( (uFileLen % sizeof(PACKAGE_INDEX)) != 0)
	{
		return FALSE;
	}
	int  uCount = uFileLen / sizeof(PACKAGE_INDEX);
	for(int i = 0; i < uCount; i++)
	{
		PACKAGE_INDEX* pAddIndex = new PACKAGE_INDEX;
		if(pAddIndex == NULL)
		{
			continue;
		}
		memcpy(pAddIndex, pRead, sizeof(PACKAGE_INDEX));
		m_PackFileIndex.AddTail(pAddIndex);
		pRead += sizeof(PACKAGE_INDEX);
	}

	delete[] pBuf;
	return TRUE;
}
*/

//-----------------------------------------------------------------------------------
// 更新文件索引表
// 参数：
//		pIndex 标识要更新的文件，如果为NULL 则更新整个文件索引表
//	返回值：
//		成功返回TRUE 失败返回FALSE
//-----------------------------------------------------------------------------------
/*
BOOL CPackageFile::SaveFileIndex(INT hFile, const PACKAGE_INDEX* pIndex)
{
	//不再需要索引文件
	return TRUE;
	//file is readonly
	if(hFile == -1)
	{
		if(m_bReadOpen)
		{
			return FALSE;
		}
	}
	if(hFile == -1)
	{
		return FALSE;
	}

	if(pIndex == NULL)
	{
		if(_chsize( hFile, 0) == -1)
		{
			ASSERT(NULL);
			return FALSE;
		}

		DWORD ver = PACKAGE_VERSOIN;
		if(!Write(hFile, &ver, sizeof(DWORD)))
		{
			return  FALSE;
		}
		if(!Write(hFile, &m_PackageHeader.dbModifyTime, sizeof(m_PackageHeader.dbModifyTime)))
		{
			return FALSE;
		}

		POSITION pos = m_PackFileIndex.GetHeadPosition();
		while(pos != NULL)
		{
			PACKAGE_INDEX* pSave = (PACKAGE_INDEX*)m_PackFileIndex.GetNext(pos);
			if(pSave != NULL)
			{
				if(!Write(hFile, pSave, sizeof(PACKAGE_INDEX)))
				{
					return FALSE;
				}
			}
		}
	}
	else
	{
		if( _lseek(hFile, sizeof(DWORD), SEEK_SET) == -1)
		{
			return FALSE;
		}
		if(!Write(hFile, &m_PackageHeader.dbModifyTime, sizeof(m_PackageHeader.dbModifyTime)))
		{
			return FALSE;
		}
		if( _lseek(hFile, 0, SEEK_END) == -1)
		{
			return FALSE;
		}

		///
		ASSERT(NULL);
		//注意，查找到指定的Index 进行更新
		//..
		//..
		//..
		
		if(!Write(hFile, (PVOID)pIndex, sizeof(PACKAGE_INDEX)))
		{
			return FALSE;
		}
	}

	
	return TRUE;
} */


/*
void CPackageFile::GetIndexFileName(const char* lpszFileName, char* lpIndexFile)
{
	strcpy(lpIndexFile, lpszFileName);
	char *ptr = lpIndexFile + strlen(lpIndexFile) - 1;
	while(ptr >= lpIndexFile)
	{
		if(*ptr == '.')break;
		ptr --;
	}
	ptr++;
    ptr[0] = 'i';
	ptr[1] = 'd';
	ptr[2] = 'x';
	ptr[3] = '\0';
}*/

void CPackageFile::GetBackupFileName(const char* lpszFileName, char* lpIndexFile)
{
	strcpy(lpIndexFile, lpszFileName);
	char *ptr = lpIndexFile + strlen(lpIndexFile) - 1;
	while(ptr >= lpIndexFile)
	{
		if(*ptr == '.')break;
		ptr --;
	}
	ptr++;
    ptr[0] = 'b';
	ptr[1] = 'a';
	ptr[2] = 'k';
	ptr[3] = '\0';
}

//-----------------------------------------------------------------------------------
// 打开包文件
// 参数：
//		lpszFileName      文件名
//		dwOpenMode        打开文件 GL_FILE_OPEN_WRITE GL_FILE_OPEN_READ
//	返回值：
//		成功回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Open(LPCTSTR lpszFileName, DWORD dwOpenMode)
{
	Close();

	if(lpszFileName == NULL)
	{
		return FALSE;
	}

	StrCpy(m_szPathName,lpszFileName);
	INT hFile;
	if(dwOpenMode == GL_FILE_OPEN_READ)
	{
		hFile = __open(lpszFileName, _O_BINARY | _O_RDONLY, _S_IREAD);
		m_bReadOpen = TRUE;
	}
	else
	{
		m_bReadOpen = FALSE;
		hFile = __open(lpszFileName, _O_BINARY | _O_RDWR, 0);
	}

	//尝试重复份文件恢复
	if(hFile == -1)
	{
		TCHAR szBackFile[MAX_PATH];
		ZeroMemory(szBackFile, sizeof(szBackFile));
		StrCpy(szBackFile, lpszFileName);
		StrCat(szBackFile, _T(".bak"));
		hFile = __open(szBackFile, _O_RDONLY, 0);
		if(hFile != -1)
		{
			_close(hFile);
			hFile = -1;
			if(__rename(szBackFile,lpszFileName) == 0)
			{
				return Open(lpszFileName);
			}
		}
	}

	//创建文件
	if(hFile == -1)
	{
		hFile = __open(lpszFileName, _O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE);
	}
	return Open(hFile);
}


//-----------------------------------------------------------------------------------
// 向包增加一个文件
// 参数
//		lpszFileName	  文件名
//		lpszPathName      文件路径
//		lpszAppendInfo    文件附加信息文件
//		bCompress	      文件是否压缩
//	返回值：
//		成功返回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::AddFile(LPCTSTR lpszFileName, LPCTSTR lpszPathFile, UINT uMothedForExist, BOOL bSec, LPCTSTR lpszAppendInfoFile, BOOL bCompress)
{
	if(m_bReadOpen)
	{
		return FALSE;
	}
	//检查文件是否存在
	if(lpszFileName == NULL || lpszPathFile == NULL)
	{
		return FALSE;
	}

	BYTE *pbyFileData = NULL;
	UINT  uFileDataLen = 0;
	BYTE *pbyAppendInfoData = NULL;
	UINT  uAppendInfoDataLen = 0;
	UINT uLen = -1;

	//读取文件
	INT hFile = __open(lpszPathFile, _O_BINARY | _O_RDONLY, _S_IREAD);
	uLen = _filelengthi64(hFile);
	pbyFileData = Read(hFile, uLen, 0);
	uFileDataLen = uLen;
	_close(hFile);

	//读取文件附加信息
	uLen = 0;
	if(lpszAppendInfoFile != NULL)
	{
		hFile = __open(lpszAppendInfoFile, _O_BINARY | _O_RDONLY, _S_IREAD);
		if(hFile != -1)
		{
			uLen = _filelengthi64(hFile);
			if(uLen == 0)
			{
				return FALSE;
			}
			pbyAppendInfoData = Read(hFile, uLen, 0);
			uAppendInfoDataLen = uLen;
			_close(hFile);
		}
	}

	BOOL bRet = AddFile(lpszFileName, pbyFileData, uFileDataLen, uMothedForExist, pbyAppendInfoData, bSec, uAppendInfoDataLen, bCompress);
	if(pbyFileData != NULL)
	{
	//	delete pbyFileData;
		free(pbyFileData);
	}
	if(pbyAppendInfoData != NULL)
	{
	//	delete pbyAppendInfoData;
		free(pbyAppendInfoData);
	}
	return bRet;
}



//-----------------------------------------------------------------------------------
// 从指定的位置读取指定长度的数据
// 参数：
//		hFile			已经打开的文件句柄
//		uRead			要读取的字节数，-1从文件开始处读取整个文件内容
//		lReadPosition	读取的开始位置，-1从当前位置开始读
//	返回值：
//		文件内容，些指针要由用户释放，如果读取失败返回NULL
//-----------------------------------------------------------------------------------
BYTE* CPackageFile::Read(INT hFile, UINT uRead, UINT lReadPosition) const
{
    if(hFile == -1)
	{
		return NULL;
	}

	UINT uReadLen = uRead;
	if( (uRead == 0) || (uRead > FILE_PACKAGE_MAX_LENGTH) )
	{
		uReadLen = (UINT)_filelengthi64(hFile);
		if(uReadLen <= 0)
		{
			return NULL;
		}
		if( _lseeki64(hFile,0,SEEK_SET) == -1)
		{
			return NULL;
		}
	}
	else if(lReadPosition < FILE_PACKAGE_MAX_LENGTH)
	{
		if( _lseeki64(hFile, lReadPosition, SEEK_SET) == -1)
		{
			return NULL;
		}
	}
	BYTE* pBuf = (BYTE *)malloc(uReadLen);/// new BYTE[uReadLen];
	if(pBuf == NULL)
	{
		return NULL;
	}

	if(uReadLen != (UINT)_read(hFile, pBuf, uReadLen))
	{
	//	delete[] pBuf;
		free(pBuf);
		return NULL;
	}
	return pBuf;
}

INT		CPackageFile::ReadTo(INT hFile, BYTE *pBufferTo, UINT nBufferLength, UINT uRead, UINT lReadPosition  )
{
	if(hFile == -1)
	{
		return -1;
	}

	UINT uReadLen = uRead;
	if( (uRead == 0) || (uRead > FILE_PACKAGE_MAX_LENGTH) )
	{
		uReadLen = (UINT)_filelengthi64(hFile);
		if(uReadLen <= 0)
		{
			return -1;
		}
		if( _lseeki64(hFile,0,SEEK_SET) == -1)
		{
			return -1;
		}
	}
	else if(lReadPosition < FILE_PACKAGE_MAX_LENGTH )
	{
		if( _lseeki64(hFile, lReadPosition, SEEK_SET) == -1)
		{
			return NULL;
		}
	}
	
	if(uReadLen > nBufferLength)
	{
		return -1;
	}

	BYTE* pBuf = (BYTE *)pBufferTo;/// new BYTE[uReadLen];

	if(uReadLen != (UINT)_read(hFile, pBuf, uReadLen))
	{
	//	delete[] pBuf;		
		return -1;
	}
	return uReadLen;
}
//-----------------------------------------------------------------------------------
// 在指定的位置写入指定长度的数据
// 参数：
//		hFile			已经打开的文件句柄
//		pBuf			要写入的数据
//		uBufLen			数据长度
//		lWritePosition	写入位置，-1在当前位置写入
//	返回值：
//		成功返回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Write(INT hFile, const void * pBuf, UINT uBufLen, UINT lWritePosition)
{
	if(hFile == -1 || pBuf == NULL || uBufLen < 0)
	{
		return FALSE;
	}

	if(lWritePosition < FILE_PACKAGE_MAX_LENGTH )
	{
		if( _lseeki64(hFile, lWritePosition, SEEK_SET) == -1)
		{
			return FALSE;
		}
	}

	if((int)uBufLen != _write(hFile, pBuf, uBufLen) )
	{
		return FALSE;
	}
	return TRUE;
}

VOID	CPackageFile::WritePackageFileHeader( const PACKAGE_FILE_HEADER &ph )
{
	if( ph.bSecIndex < 64 )
	{
		Write(m_hFile, &ph, sizeof(PACKAGE_FILE_HEADER));
	}
	else
	{
		PACKAGE_FILE_HEADER enH = ph;
		enH.bSecLen = strlen(enH.szFileName);
		ENCRYPT( (BYTE *)enH.szFileName, 260, m_PackageHeader.secPassword[ ph.bSecIndex - 64 ], 888888, 16);
		Write( m_hFile, &enH, sizeof(PACKAGE_FILE_HEADER) );
	}
}

BOOL	CPackageFile::ReadPackageFileHeader( PACKAGE_FILE_HEADER &ph ,BOOL bEncrypt) const
{
	if( m_PackageHeader.dwFileInfoOffset > sizeof(PACKAGE_FILE_HEADER) )
	{
		UINT nPos = _telli64(m_hFile);
		if( nPos >= (m_PackageHeader.dwFileInfoOffset - sizeof(PACKAGE_FILE_HEADER)) )
		{
			return FALSE;
		}
	}

	if (_read(m_hFile, &ph, sizeof(PACKAGE_FILE_HEADER) ) != sizeof(PACKAGE_FILE_HEADER) ) 
		return FALSE;
	if( ph.bSecIndex >= 64 && bEncrypt)
	{
		ENCRYPT((BYTE *) ph.szFileName, 260, m_PackageHeader.secPassword[ ph.bSecIndex - 64 ], 888888, 16);
	}
	return TRUE;
}

//-----------------------------------------------------------------------------------
// 向包增加一个文件
// 参数：
//		lpszFileName		文件名，不包含路径
//		pbyFileData			文件内容
//		uFileDataLen		文件长度
//		pbyAppendInfoData	文件附加信息，没有附加信息应为NULL
//		uAppendInfoDataLen	文件附加信息长度
//		bCompress`			是否进行压缩
//	返回值：
//		成功返回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::AddFile(LPCTSTR lpszFileName, BYTE *pbyFileData, UINT uFileDataLen, UINT uMothedForExist, BYTE *pbyAppendInfoData, BOOL bSec, UINT uAppendInfoDataLen, BOOL bCompress)
{
	if(m_bReadOpen)
	{
		return FALSE;
	}

	if(pbyFileData == NULL || uFileDataLen <= 0 || lpszFileName == NULL)
	{
		return FALSE;
	}

	//检查文件是否已经存在
	if(uMothedForExist == GL_MOTHED_NONE)
	{
		if(CPackageFile::FileExist(lpszFileName))
		{
			return FALSE;
		}
	}
	else
	{
		DelFile(lpszFileName, uMothedForExist);
	}

	PACKAGE_FILE_HEADER FileHeader;
	StrCpy(FileHeader.szFileName, ConvertLower(lpszFileName).c_str() );
	FileHeader.byModify = GL_FILE_STATE_NORMAL;
	FileHeader.uAppendInfoLength = uAppendInfoDataLen;
	FileHeader.bCompress = bCompress;
	
	{
		MD5_CTX mctx;
		MD5Init(&mctx);
		MD5Update( &mctx, pbyFileData, uFileDataLen );
		MD5Final( FileHeader.szBufferID, &mctx );
	}
	if( bSec && m_PackageHeader.dwSec)
	{
		INT n = 0;
		//for( INT i=0; i<n; ++i )
		//{
		//	n += FileHeader.szFileName[i];
		//}
		FileHeader.bSecIndex = 64 + n%8;
	}
	else
		FileHeader.bSecIndex = 0;

	BYTE* pFileData = pbyFileData;
	INT   nFileLen  = (INT)uFileDataLen;

	//处理文件压缩，如果文件压缩失败或压缩后文件更大，则不进行压缩
	if(bCompress)
	{
		pFileData = (BYTE*)gpZipBuf(m_pFuncCompress, pFileData, nFileLen);
		if(pFileData == NULL)
		{
			pFileData = pbyFileData;
			nFileLen = (INT)uFileDataLen;
			FileHeader.bCompress = FALSE;
		}
		else if(nFileLen >= (INT)uFileDataLen)
		{
		//	delete[] pFileData;
			free(pFileData);
			pFileData = pbyFileData;
			nFileLen = (INT)uFileDataLen;
			FileHeader.bCompress = FALSE;
		}
	}
	FileHeader.uFileLength = nFileLen;
	if( FileHeader.bSecIndex >= 64  )
	{
		///Sec
		//CBlowfish bf;
		//bf.InitializeBlowfish( m_PackageHeader.secPassword[ FileHeader.bSecIndex - 64 ], 16 );
		//char s[32];
		//strcpy( s, SEC_KEY_PARAM, 32 );
		//bf.Encrypt( SEC_KEY_PARAM
		ENCRYPT( pFileData, nFileLen, m_PackageHeader.secPassword[ FileHeader.bSecIndex - 64 ], 888888, 16);		
	}

	UINT nFileInfoOffset = m_PackageHeader.dwFileInfoOffset;
	
	//开始写入数据
	BeginSave();

	if( _lseeki64(m_hFile, 0, SEEK_END) == -1)
	{
		return FALSE;
	}

	//更新文件索引表
	UINT nPos = _telli64(m_hFile);

	if( nFileInfoOffset > SAVE_FLAG_POSITION )
	{
		if( nPos > nFileInfoOffset )
		{
			_lseeki64(m_hFile, nFileInfoOffset, SEEK_SET );
		}
	}
	PPACKAGE_INDEX pIndex = new PACKAGE_INDEX;
	if(pIndex != NULL)
	{
		pIndex->byModifyFlag = GL_FILE_STATE_NORMAL;
		strcpy(pIndex->szFileName, ConvertLower(lpszFileName ).c_str());
		pIndex->lFilePosInPackage = _telli64(m_hFile);
		m_PackFileIndex[pIndex->szFileName] = pIndex;
		//m_PackFileIndex.AddTail(pIndex);
		//SaveFileIndex(-1, pIndex);
	}
	
//	Write(m_hFile, &FileHeader, sizeof(FileHeader));
	WritePackageFileHeader( FileHeader );
	BOOL bSuccess = Write(m_hFile, pFileData, nFileLen);

	//加入附加信息
	if(pbyAppendInfoData != NULL && uAppendInfoDataLen > 0)
	{
		bSuccess = Write(m_hFile, pbyAppendInfoData, uAppendInfoDataLen);		
	}
	
	nPos += FileHeader.uAppendInfoLength + FileHeader.uFileLength + sizeof(FileHeader);
	_chsize_s(m_hFile, _telli64(m_hFile));
	EndSave();
	if(FileHeader.bCompress)
	{
	//	delete[] pFileData;
		free(pFileData);
	}

	return bSuccess;
}

//-----------------------------------------------------------------------------------
// 从包中删除一个文件
// 参数：
//		lpszFileName		文件名，不包含路径
//	返回值：
//		删除成功返回TRUE，文件不存在或删除失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::DelFile(LPCTSTR lpszFileName, INT nDelMothed)
{
	if(m_bReadOpen)
	{
		return FALSE;
	}
	if(nDelMothed <= GL_MOTHED_NONE || nDelMothed > GL_MOTHED_MARK_DEL)
	{
		return FALSE;
	}
	//检查文件是否已经存在
	FileIndexList::iterator it = m_PackFileIndex.find(lpszFileName);
	if ( it != m_PackFileIndex.end() )
	{
		if( it->second->byModifyFlag != GL_FILE_STATE_MARK_DEL )
		{
				PACKAGE_FILE_INFO info;
				GetFileInfo(it, info);
				m_PackageHeader.dwDelNumberInBytes += info.uFileLength;
				m_PackageHeader.dwDelNumberInBytes += info.uAppendInfoLength;

				BeginSave();
				it->second->byModifyFlag = GL_MOTHED_MARK_DEL;	

				Write(m_hFile, &it->second->byModifyFlag, sizeof(BYTE), it->second->lFilePosInPackage);
				
	
				EndSave();

				///删除文件保存文件头
				SavePackageHeader(m_hFile);
				return TRUE;
		}
	}
	return FALSE;

	//BOOL bRet = FALSE;
	//PPACKAGE_INDEX pIndex = NULL;
	//POSITION pos = m_PackFileIndex.GetHeadPosition();
	//POSITION DelPos = pos;
	//LONG lIndexPos = 0;
	//while( pos != NULL)
	//{
	//	pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
	//	if(pIndex == NULL)
	//	{
	//		return FALSE;
	//	}
	//	if(pIndex->byModifyFlag != GL_FILE_STATE_MARK_DEL)
	//	{
	//		//文件已经存在
	//		if(StrCmpI(pIndex->szFileName,lpszFileName) == 0)
	//		{
	//			BeginSave();
	//			pIndex->byModifyFlag = GL_MOTHED_MARK_DEL;	

	//			Write(m_hFile, &pIndex->byModifyFlag, sizeof(BYTE), pIndex->lFilePosInPackage);
	//			
	//			//不支持文件索引功能
	//			//SaveFileIndex(m_hIndexFile, pIndex);
	//			EndSave();
	//			bRet = TRUE;return TRUE;
	//		}
	//	}
	//	lIndexPos += sizeof(PACKAGE_INDEX);
	//}

	//return bRet;
}



//-----------------------------------------------------------------------------------
// 复制内存对像
// 参数：
//		pBuf			待复制的数据
//		uBufLen			数据长度
//	返回值：
//		成功返回数据的复本，失败返回NULL
//-----------------------------------------------------------------------------------
PVOID	CPackageFile::CopyData(PVOID pBuf, UINT uBufLen)
{
	BYTE* pCopy = (BYTE *)malloc(uBufLen);///new BYTE[uBufLen];
	if(pCopy != NULL)
	{
		memcpy(pCopy, pBuf, uBufLen);
	}
	return pCopy;
}

//-----------------------------------------------------------------------------------
// 从包中读一个文件到缓冲区
// 参数：
//		lpszFileName		文件名，不包含路径
//		pbyFileData[out]	返回文件内存
//		puFileLen[out]		返回文件长度
//		pbyAppendInfoData	返回文件附加信息，如果NULL则不读取文件附回信息
//		puAppendInfoDataLen	返回文件附加信息长度，如果为NULL则不读取文件附回信息
//	返回值：
//		成功返回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::GetFile(LPCTSTR lpszFileName, BYTE** pbyFileData, UINT* puFileLen, BYTE** pbyAppendInfoData, UINT* puAppendInfoDataLen)
{
	if(pbyFileData == NULL || lpszFileName == NULL || puFileLen == NULL)
	{
		return FALSE;
	}

	char strFileName[MAX_PATH];
	strcpy(strFileName,lpszFileName);
	FileIndexList::const_iterator it =m_PackFileIndex.find(strlwr(strFileName));
	if ( it == m_PackFileIndex.end() )
	{
		return FALSE;
	}
	PPACKAGE_INDEX pIndex = it->second;

	//PPACKAGE_INDEX pIndex = NULL;
	//POSITION pos = m_PackFileIndex.GetHeadPosition();
	//BOOL bFind = FALSE;
	//while(pos != NULL)
	//{
	//	pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
	//	if(pIndex->byModifyFlag == GL_FILE_STATE_NORMAL)
	//	{
	//		if(StrCmpI(pIndex->szFileName,lpszFileName) == 0)
	//		{
	//			bFind = TRUE;
	//			break;
	//		}
	//	}
	//}
	//if(!bFind)
	//{
	//	return FALSE;
	//}

	//读文件
	UINT uOffset = pIndex->lFilePosInPackage;
	PACKAGE_FILE_HEADER FileHeader;
	int sizeofFH = sizeof(PACKAGE_FILE_HEADER);
	if( _lseeki64(m_hFile, uOffset, SEEK_SET) == -1)
	{
		return FALSE;
	}
	if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
	{
		return FALSE;
	}
	UINT uFileLen = FileHeader.uFileLength;
	UINT uDataLen = FileHeader.uAppendInfoLength;
	BYTE* pSrcData = NULL;
	
	pSrcData = Read(m_hFile, uFileLen);
	

	if(pSrcData == NULL)
	{
		return FALSE;
	}

	if(FileHeader.bCompress)
	{
		int nDataLen = uFileLen;
		*pbyFileData = (BYTE*)gpUnzipBuf(m_pFuncUnCompress,pSrcData,nDataLen);
		if(*pbyFileData == NULL)
		{
		//	delete[] pSrcData;
			free(pSrcData);
			return FALSE;
		}
		uFileLen = nDataLen;
	//	delete[] pSrcData;
		free(pSrcData);
	}
	else
	{
		*pbyFileData = pSrcData;
	}
	int offPw = offsetof(PACKAGE_HEADER, secPassword);
	if( FileHeader.bSecIndex >= 64 && FileHeader.bSecLen)
	{
		ENCRYPT( *pbyFileData, FileHeader.uFileLength, m_PackageHeader.secPassword[FileHeader.bSecIndex-64], 888888, 16);
	}
	*puFileLen = uFileLen;

	//读附加信息
	if(pbyAppendInfoData != NULL && puAppendInfoDataLen != NULL)
	{
		if(uDataLen > 0)
		{
			*pbyAppendInfoData = Read(m_hFile, uDataLen);
			*puAppendInfoDataLen = uDataLen;
		}
		else
		{
			*pbyAppendInfoData = NULL;
			*puAppendInfoDataLen = 0;
		}
	}
	return TRUE;
}




//-----------------------------------------------------------------------------------
// 删除包中标记删除的文件，由DelFile  指定 GL_MOTHED_MARK_DEL 产生
// 参数：
//		
//返回值：
//		
//-----------------------------------------------------------------------------------
void CPackageFile::ClearMarkFile()
{
	if(m_bReadOpen)return;

	PPACKAGE_INDEX pIndex = NULL;
	for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
	{
		if( it->second->byModifyFlag == GL_FILE_STATE_MARK_DEL)
		{
			pIndex = it->second;
			break;
		}
	}

	if ( NULL == pIndex )
		return;

	//BOOL bFind = FALSE;
	//PPACKAGE_INDEX pIndex = NULL;
	//POSITION pos = m_PackFileIndex.GetHeadPosition();
	//while(pos != NULL)
	//{
	//	pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
	//	if( pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
	//	{
	//		bFind = TRUE;
 //           break;			
	//	}
	//}
	//if(!bFind)
	//{
	//	return;
	//}

    //保存文件内容
	TCHAR szBackFile[MAX_PATH];
	TCHAR szPathName[MAX_PATH];
	//TCHAR szIndexFile[MAX_PATH];

	StrCpy(szPathName, m_szPathName);

	//ZeroMemory(szIndexFile, sizeof(szIndexFile));
	ZeroMemory(szBackFile, sizeof(szBackFile));
	//GetIndexFileName(m_szPathName, szIndexFile);
	GetBackupFileName(m_szPathName, szBackFile);
	
	if(!Save(szBackFile))
	{
        return;
	}
	
	Close();

	//DeleteFile(szIndexFile);

	if(DeleteFile(szPathName))
	{
		__rename(szBackFile, szPathName);
	}
	
	Open(szPathName, GL_FILE_OPEN_WRITE);
}

void	CPackageFile::RepareContent()
{
	if(m_bReadOpen)return;

	PPACKAGE_INDEX pIndex = NULL;
	PACKAGE_FILE_INFO info;
	DWORD dEndPosition = 0;
	for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
	{
		if( it->second->byModifyFlag == GL_FILE_STATE_MARK_DEL)
		{
			pIndex = it->second;
			break;
		}

		if( GetFileInfo( it, info ) )
		{
			DWORD dFileEnd = info.uFileLength + it->second->lFilePosInPackage + info.uAppendInfoLength + sizeof(PACKAGE_FILE_HEADER);
			if( dFileEnd > dEndPosition )
				dEndPosition = dFileEnd;
		}
	}

	if ( (NULL == pIndex) && (dEndPosition == m_PackageHeader.dwFileInfoOffset) )
		return;

	//BOOL bFind = FALSE;
	//PPACKAGE_INDEX pIndex = NULL;
	//POSITION pos = m_PackFileIndex.GetHeadPosition();
	//while(pos != NULL)
	//{
	//	pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
	//	if( pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
	//	{
	//		bFind = TRUE;
 //           break;			
	//	}
	//}
	//if(!bFind)
	//{
	//	return;
	//}

    //保存文件内容
	TCHAR szBackFile[MAX_PATH];
	TCHAR szPathName[MAX_PATH];
	//TCHAR szIndexFile[MAX_PATH];

	StrCpy(szPathName, m_szPathName);

	//ZeroMemory(szIndexFile, sizeof(szIndexFile));
	ZeroMemory(szBackFile, sizeof(szBackFile));
	//GetIndexFileName(m_szPathName, szIndexFile);
	GetBackupFileName(m_szPathName, szBackFile);
	
	if(!SaveUseIndex(szBackFile))
	{
        return;
	}
	
	Close();

	//DeleteFile(szIndexFile);

	if(DeleteFile(szPathName))
	{
		__rename(szBackFile, szPathName);
	}
	
	Open(szPathName, GL_FILE_OPEN_WRITE);
}

//-----------------------------------------------------------------------------------
// 保存内存到磁盘
// 参数：
//		lpszFileName		文件名，如果为NULL使用打开时的文件名
//	返回值：
//		成功返回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::Save(LPCTSTR lpszFileName)
{
	if(m_hFile == -1 || lpszFileName == NULL)
	{
		return FALSE;
	}

	if(StrCmpI(lpszFileName,m_szPathName) == 0)
	{
		return TRUE;
	}

	//TCHAR szIndexFile[MAX_PATH];
	//ZeroMemory(szIndexFile, sizeof(szIndexFile));
	//GetIndexFileName(lpszFileName, szIndexFile);

	INT hFile = __open(lpszFileName, _O_BINARY | _O_RDWR, 0);
	if(hFile == -1)
	{
		hFile = __open(lpszFileName, _O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE);
	}
	
	if(hFile == -1)
	{
		if(hFile != -1)
		{
			_close(hFile);
		}
		return FALSE;
	}
	
	_chsize_s(hFile, 0);
	
	DWORD dwTemp = m_PackageHeader.dwPackageVersion;
	m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
	m_PackageHeader.dbModifyTime = GetSystemTime();
	UINT fInfoOffset = m_PackageHeader.dwFileInfoOffset;
	UINT fInfoLength = m_PackageHeader.dwFileInfoLength;
	m_PackageHeader.dwFileInfoOffset = 0;
	m_PackageHeader.dwFileInfoLength = 0;
	SavePackageHeader(hFile);
	m_PackageHeader.dwPackageVersion = dwTemp;
	m_PackageHeader.dwFileInfoOffset = fInfoOffset;
	m_PackageHeader.dwFileInfoLength = fInfoLength;
	
	BeginSave(hFile);
	//保存文件内容
	BYTE* pBuf = NULL;
	PACKAGE_FILE_HEADER FileHeader;
	
	UINT offset = 0;
	if( m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
	{
		offset = FILE_START_POSITION_1_0;
	}
	else
	{
		offset = FILE_START_POSITION;
	}
	if(_lseeki64(m_hFile, offset, SEEK_SET) == -1)
	{
		return FALSE;
	}

/// OldFile Need Recovery, the info of file is not exist
//	while(sizeof(FileHeader) == _read(m_hFile, &FileHeader, sizeof(FileHeader)))
	while( ReadPackageFileHeader(FileHeader,FALSE) )
	{
		UINT nDataLen = FileHeader.uAppendInfoLength + FileHeader.uFileLength;
		if(FileHeader.byModify == GL_FILE_STATE_MARK_DEL)
		{
			if( _lseeki64(m_hFile, nDataLen, SEEK_CUR) == -1)
			{
				return FALSE;
			}
			continue;
		}
		if(!Write(hFile, &FileHeader, sizeof(FileHeader)))
		{
			return FALSE;
		}
		//WritePackageFileHeader(FileHeader);
		pBuf = Read(m_hFile, nDataLen);
		if(pBuf == NULL)
		{
			return FALSE;
		}
		if(!Write(hFile, pBuf, nDataLen))
		{
		//	delete[] pBuf;
			free(pBuf);
			return FALSE;
		}
	//	delete[] pBuf;
		free(pBuf);
	}

	EndSave(hFile);

/// can't do here, the index is changed
/// need recreate
///	SavePacketV12IndexInfo(hFile);
	_close(m_hFile);
	
	//_close(m_hIndexFile);

	m_hFile = hFile;
	StrCpy(m_szPathName, lpszFileName);

	m_bReadOpen = FALSE;
	return TRUE;
}


//-----------------------------------------------------------------------------------
// 保存内存到磁盘
// 参数：
//		lpszFileName		文件名，如果为NULL使用打开时的文件名
//	返回值：
//		成功返回TRUE，失败返回FALSE
//-----------------------------------------------------------------------------------
BOOL CPackageFile::SaveUseIndex(LPCTSTR lpszFileName)
{
	if(m_hFile == -1 || lpszFileName == NULL)
	{
		return FALSE;
	}

	if(StrCmpI(lpszFileName,m_szPathName) == 0)
	{
		return TRUE;
	}

	//TCHAR szIndexFile[MAX_PATH];
	//ZeroMemory(szIndexFile, sizeof(szIndexFile));
	//GetIndexFileName(lpszFileName, szIndexFile);

	INT hFile = __open(lpszFileName, _O_BINARY | _O_RDWR, 0);
	if(hFile == -1)
	{
		hFile = __open(lpszFileName, _O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE);
	}
	
	if(hFile == -1)
	{
		if(hFile != -1)
		{
			_close(hFile);
		}
		return FALSE;
	}
	
	_chsize_s(hFile, 0);
	
	DWORD dwTemp = m_PackageHeader.dwPackageVersion;
	m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
	m_PackageHeader.dbModifyTime = GetSystemTime();
	UINT fInfoOffset = m_PackageHeader.dwFileInfoOffset;
	UINT fInfoLength = m_PackageHeader.dwFileInfoLength;
	m_PackageHeader.dwFileInfoOffset = 0;
	m_PackageHeader.dwFileInfoLength = 0;
	SavePackageHeader(hFile);
	m_PackageHeader.dwPackageVersion = dwTemp;
	m_PackageHeader.dwFileInfoOffset = fInfoOffset;
	m_PackageHeader.dwFileInfoLength = fInfoLength;
	
	BeginSave(hFile);
	//保存文件内容
	BYTE* pBuf = NULL;
	PACKAGE_FILE_HEADER FileHeader;
	
	UINT offset = 0;
	if( m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
	{
		offset = FILE_START_POSITION_1_0;
	}
	else
	{
		offset = FILE_START_POSITION;
	}
	if(_lseeki64(m_hFile, offset, SEEK_SET) == -1)
	{
		return FALSE;
	}

/// OldFile Need Recovery, the info of file is not exist
//	while(sizeof(FileHeader) == _read(m_hFile, &FileHeader, sizeof(FileHeader)))
//	while( ReadPackageFileHeader(FileHeader,FALSE) )
	for ( FileIndexList::iterator it =m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
	{
	//	std::string sFileName = it->first;

		if( it->second->byModifyFlag == GL_FILE_STATE_MARK_DEL )
		{
			continue;
		}
		
		if( _lseeki64(m_hFile, it->second->lFilePosInPackage, SEEK_SET) == -1)
		{
			return FALSE;
		}
		//if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
		//{
		//	return FALSE;
		//}

		if( !ReadPackageFileHeader(FileHeader, FALSE) )
			return FALSE;
		

		UINT nDataLen = FileHeader.uAppendInfoLength + FileHeader.uFileLength;
		if(FileHeader.byModify == GL_FILE_STATE_MARK_DEL)
		{
			continue;
		}
		if(!Write(hFile, &FileHeader, sizeof(FileHeader)))
		{
			return FALSE;
		}
		//WritePackageFileHeader(FileHeader);
		pBuf = Read(m_hFile, nDataLen);
		if(pBuf == NULL)
		{
			return FALSE;
		}
		if(!Write(hFile, pBuf, nDataLen))
		{
		//	delete[] pBuf;
			free(pBuf);
			return FALSE;
		}
	//	delete[] pBuf;
		free(pBuf);
	}

	EndSave(hFile);

/// can't do here, the index is changed
/// need recreate
///	SavePacketV12IndexInfo(hFile);
	_close(m_hFile);
	
	//_close(m_hIndexFile);

	m_hFile = hFile;
	StrCpy(m_szPathName, lpszFileName);

	m_bReadOpen = FALSE;
	return TRUE;
}


ConFileIndex CPackageFile::GetFirstFilePosition()
{
	return m_PackFileIndex.begin();
}

BOOL CPackageFile::IsEndFilePosition(ConFileIndex cit)
{
	return (cit == m_PackFileIndex.end());
}

BOOL CPackageFile::GetFileInfo(ConFileIndex cit, PACKAGE_FILE_INFO &fInfo)
{
	PPACKAGE_INDEX pIndex = cit->second;//(PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);

	if(pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
	{
		return FALSE;//GetNextFile(pos);
	}

	
	PACKAGE_FILE_HEADER FileHeader;
	if( _lseeki64(m_hFile, pIndex->lFilePosInPackage, SEEK_SET) == -1)
	{
		return FALSE;
	}
	//if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
	//{
	//	return FALSE;
	//}

	if( !ReadPackageFileHeader(FileHeader) )
		return FALSE;
	
	StrCpy(fInfo.szFileName, pIndex->szFileName);
	memcpy( fInfo.szBufferID, FileHeader.szBufferID, 16 );
	fInfo.bCompress = FileHeader.bCompress;
	fInfo.uAppendInfoLength = FileHeader.uAppendInfoLength;
	fInfo.uFileLength = FileHeader.uFileLength;
	fInfo.bSecIndex = FileHeader.bSecIndex;
	return TRUE;
}

//-----------------------------------------------------------------------------------
// 返回包文件起始位置，用于GetNextFile
// 参数：
//		
//	返回值：
//		如果不存在文件，返回NULL
//-----------------------------------------------------------------------------------
//POSITION CPackageFile::GetFirstFilePosition()
//{
//	return m_PackFileIndex.GetHeadPosition();
//}

//-----------------------------------------------------------------------------------
// 读取下一个位置文件
// 参数：
//		pos			文件位置 ,用GetFirstFile GetNextFile 返回
//	返回值：
//		文件内容，些指针要由用户释放
//-----------------------------------------------------------------------------------
//PACKAGE_FILE_INFO*  CPackageFile::GetNextFile(POSITION& pos)
//{
//	if(pos == NULL)
//	{
//		return NULL;
//	}
//	PPACKAGE_INDEX pIndex = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
//
//	if(pIndex->byModifyFlag == GL_FILE_STATE_MARK_DEL)
//	{
//		return GetNextFile(pos);
//	}
//
//	
//	PACKAGE_FILE_HEADER FileHeader;
//	if( _lseek(m_hFile, pIndex->lFilePosInPackage, SEEK_SET) == -1)
//	{
//		return NULL;
//	}
//	if( sizeof(FileHeader) != _read(m_hFile, &FileHeader, sizeof(FileHeader)))
//	{
//		return NULL;
//	}
//
//	PACKAGE_FILE_INFO *pFileInfo = new PACKAGE_FILE_INFO;
//	if(pFileInfo == NULL)
//	{
//		return NULL;
//	}
//	StrCpy(pFileInfo->szFileName, pIndex->szFileName);
//	pFileInfo->bCompress = FileHeader.bCompress;
//	pFileInfo->uAppendInfoLength = FileHeader.uAppendInfoLength;
//	pFileInfo->uFileLength = FileHeader.uFileLength;
//	return pFileInfo;
//}


//-----------------------------------------------------------------------------------
// 并闭文件，释放内存
// 参数：
//		
//	返回值：
//		
//-----------------------------------------------------------------------------------
void CPackageFile::Close()
{
	m_bReadOpen = TRUE;
	ZeroMemory(m_szPathName, sizeof(m_szPathName));
	ZeroMemory(&m_PackageHeader,sizeof(m_PackageHeader));
	StrCpy(m_PackageHeader.szPackIdentifier, _T(FILE_PACKET_IDENTIFY));
	StrCpy(m_PackageHeader.szPackageName,_T("User Package"));
	m_PackageHeader.dwPackageVersion = PACKAGE_VERSOIN;
	if(m_hFile != -1)
	{
		_close(m_hFile);
		m_hFile = -1;
	}

	for ( FileIndexList::iterator it =m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
	{
		delete it->second;
	}
	m_PackFileIndex.clear();
	
	//PPACKAGE_INDEX pDel = NULL;
	//POSITION pos = m_PackFileIndex.GetHeadPosition();
	//while(pos != NULL)
	//{
	//	pDel = (PPACKAGE_INDEX)m_PackFileIndex.GetNext(pos);
	//	delete pDel;
	//}
	//m_PackFileIndex.RemoveAll();	
}

//-----------------------------------------------------------------------------------
// 写入开始更新标记
// 参数：
//
//	返回值：
//
//-----------------------------------------------------------------------------------
void CPackageFile::BeginSave(INT hFile)
{
	

	if(hFile == -1)
	{
		if(m_bReadOpen)
		{
			return;
		}
		hFile = m_hFile;
	}
	m_bySaveFlags = 1;

	///进行保存，必须重建索引	
	if( (hFile == m_hFile) &&
		((m_PackageHeader.dwFileInfoOffset != 0)
		|| (m_PackageHeader.dwFileInfoLength!=0)) )
	{
		DWORD dCurPos = _telli64(hFile);
		_chsize_s(hFile, m_PackageHeader.dwFileInfoOffset);	
		UINT dNewFileSize = m_PackageHeader.dwFileInfoOffset;
		m_PackageHeader.dwFileInfoOffset = 0;
		m_PackageHeader.dwFileInfoLength = 0;		
		_lseeki64(hFile, 0, SEEK_SET );
		SavePackageHeader(hFile);	
		if( dCurPos < dNewFileSize )
			_lseeki64(hFile, dCurPos,SEEK_SET);
		else
			_lseeki64(hFile, dNewFileSize,SEEK_SET);	///Seek To End
	}

	if(_lseeki64(hFile, SAVE_FLAG_POSITION, SEEK_SET) == -1)
	{
		SavePackageHeader(hFile);
	}
	_write(hFile, &m_bySaveFlags, sizeof(BYTE));
}

//-----------------------------------------------------------------------------------
// 写放完成更新标记
// 参数：
//
//	返回值：
//
//-----------------------------------------------------------------------------------
void CPackageFile::EndSave(INT hFile)
{
	if(hFile == -1)
	{
		if(m_bReadOpen)
		{
			return;
		}
		hFile = m_hFile;
	}
	m_bySaveFlags = 0;

//	SavePacketV12IndexInfo();


	if(_lseeki64(hFile, SAVE_FLAG_POSITION, SEEK_SET) == -1)
	{
		SavePackageHeader(hFile);
	}
	_write(hFile, &m_bySaveFlags, sizeof(BYTE));

}


//-----------------------------------------------------------------------------------
// 保存包头信息到磁盘
// 参数：
//
//	返回值：
//
//-----------------------------------------------------------------------------------
BOOL CPackageFile::SavePackageHeader(INT hFile)
{
	if(hFile == -1)
	{
		if(m_bReadOpen)
		{
			return FALSE;
		}
		hFile = m_hFile;
	}
	if(!Write(hFile, &m_PackageHeader, sizeof(m_PackageHeader), 0))
	{
		return FALSE;
	}
	return TRUE;
}


//-----------------------------------------------------------------------------------
// 从包内容创建文件索引表
// 参数：
//
//	返回值：
//
//-----------------------------------------------------------------------------------
BOOL CPackageFile::CreateFileIndex()
{
	if( _lseeki64(m_hFile, 0, SEEK_END) == -1)
	{
		return FALSE;
	}
	UINT nfilelen = _telli64(m_hFile);
	ULONG offset = FILE_START_POSITION;//_1_0;
	if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSION_1_0)
	{
		offset = FILE_START_POSITION_1_0;
	}

	//else if(m_PackageHeader.dwPackageVersion == PACKAGE_VERSOIN)
	//{
	//	offset = FILE_START_POSITION;
	//}
	if( _lseeki64(m_hFile, offset, SEEK_SET) == -1)
	{
		return FALSE;
	}

	if( !LoadPackageV12FileIndex() )
	{

		PACKAGE_FILE_HEADER FileHeader;
		ULONG lFileLen = _telli64(m_hFile);
		//while(sizeof(FileHeader) == _read(m_hFile, &FileHeader, sizeof(FileHeader)))
		while( ReadPackageFileHeader(FileHeader) )
		{
			if( (int)FileHeader.uAppendInfoLength <= 0)FileHeader.uAppendInfoLength = 0;
			if( (int)FileHeader.uFileLength <= 0) break;

			//记录完整性检查
			UINT nNextBegin = _telli64(m_hFile) + FileHeader.uFileLength + FileHeader.uAppendInfoLength;
			if(nNextBegin > nfilelen)
			{
				//TRACE("\n文件 %s 不完整 丢弃", FileHeader.szFileName);
				break;
			}

			PPACKAGE_INDEX pIndex = new PACKAGE_INDEX;
			if(pIndex == NULL)
			{
				return FALSE;
			}

			///如果是删除的文件，不应该加载，跳过去
			if( FileHeader.byModify != GL_FILE_STATE_MARK_DEL )
			{
				pIndex->byModifyFlag = FileHeader.byModify;
				pIndex->lFilePosInPackage = lFileLen;
				StrCpy(pIndex->szFileName, FileHeader.szFileName);
				m_PackFileIndex[strlwr( pIndex->szFileName)] = pIndex;
			}
			//m_PackFileIndex.AddTail(pIndex);

			//文件数据错误
			if( _lseeki64(m_hFile, FileHeader.uAppendInfoLength + FileHeader.uFileLength, SEEK_CUR) == -1)
			{
				break;
			}
			lFileLen = _telli64(m_hFile);
			if(lFileLen > nfilelen)
			{
				break;
			}
		}

		if(!m_bReadOpen)
		{
			if(lFileLen < nfilelen )
			{
				_chsize_s(m_hFile, lFileLen);
			}
		}
	}

	
	return TRUE;
}

BOOL	CPackageFile::LoadPackageV12FileIndex()
{
	int offInit = offsetof(CPackageFile, m_PackageHeader);
	if(m_PackageHeader.dwPackageVersion != PACKAGE_VERSION_1_2 )
		return FALSE;
	int startPos = FILE_START_POSITION;
	int infoOffset = offsetof(PACKAGE_HEADER_1_2,dwFileInfoOffset);
	int pvOffset = offsetof(PACKAGE_HEADER_1_2,dwPackageVersion);
	if( m_PackageHeader.dwFileInfoOffset < FILE_START_POSITION 
		|| m_PackageHeader.dwFileInfoLength < 1)
	{
		return FALSE;
	}
	//FIXFIX: 不应该这样的 by 不说害怕
	m_PackageHeader.dwFileInfoOffset += 320;
	BOOL bS = TRUE;

	INT hFile = m_hFile;
	DWORD nFileLie = _telli64(hFile);
	__int64 newpos = _lseeki64(hFile, m_PackageHeader.dwFileInfoOffset, SEEK_SET);
	if( newpos == -1)
	{
		_lseeki64( hFile, nFileLie, SEEK_SET );
		return FALSE;
	}

	/// 每个PackageHeader都存在一块
	int sizeIdx = sizeof(PACKAGE_INDEX); // 288
	int nNumHeader = m_PackageHeader.dwFileInfoLength / sizeof(PACKAGE_INDEX);
	if( nNumHeader < 1 )
	{
		_lseeki64(hFile, nFileLie, SEEK_SET);
		return FALSE;
	}
	for( int i=0; i<nNumHeader; ++i )
	{
		PACKAGE_INDEX *pIndex = new PACKAGE_INDEX;
		if (_read(m_hFile, pIndex, sizeof(PACKAGE_INDEX) ) != sizeof(PACKAGE_INDEX) ) 
		{
			///需要释放也经加载的?
			delete pIndex;
			bS = FALSE;
			break;
		}	

		if( m_PackageHeader.btInfoSecIndex >= 64 )
		{
			if (pIndex->byFileNameLen)
			{
				ENCRYPT((BYTE *) pIndex->szFileName, pIndex->byFileNameLen, m_PackageHeader.secPassword[m_PackageHeader.btInfoSecIndex - 64 ], 888888, 16);
			}
		}
		m_PackFileIndex[strlwr( pIndex->szFileName)] = pIndex;		
	}


	_lseeki64(hFile, nFileLie, SEEK_SET);

	if( !bS )
	{
		for ( FileIndexList::iterator it = m_PackFileIndex.begin() ; it != m_PackFileIndex.end() ; ++it )
		{		
			delete it->second;
		}
		m_PackFileIndex.clear();
		return FALSE;
	}
	return TRUE;
}


BOOL	CPackageFile::SavePacketV12IndexInfo(INT nReInitIndexLie)
{
	INT hFile = m_hFile;

	if(m_PackageHeader.dwPackageVersion != PACKAGE_VERSION_1_2 )
		return FALSE;

	if( nReInitIndexLie > 0 )
	{
		m_PackageHeader.dwFileInfoOffset = 0;
		m_PackageHeader.dwFileInfoLength = 0;
	}

	if( m_PackageHeader.dwFileInfoOffset < 1 )
	{
		///重新计算偏移和大小
		ConFileIndex itLie = m_PackFileIndex.begin();
		ConFileIndex itEnd = m_PackFileIndex.end();
		PACKAGE_FILE_INFO info;
		DWORD	dEndPosition = 0;	
		INT nNumOfFileIndex=0;
		for( ;itLie!=itEnd; ++itLie )
		{
			++nNumOfFileIndex;
			if( GetFileInfo( itLie, info ) )
			{
				DWORD dFileEnd = info.uFileLength + itLie->second->lFilePosInPackage + info.uAppendInfoLength + sizeof(PACKAGE_FILE_HEADER);
				if( dFileEnd > dEndPosition )
					dEndPosition = dFileEnd;
			}
		}
		m_PackageHeader.dwFileInfoOffset = dEndPosition;
		m_PackageHeader.dwFileInfoLength = nNumOfFileIndex * sizeof(PACKAGE_INDEX);
		m_PackageHeader.btInfoSecIndex = 6+64;
	}
	
	if( m_PackageHeader.dwFileInfoLength > 0 )
	{		
		_lseeki64(hFile, m_PackageHeader.dwFileInfoOffset, SEEK_SET);
		{
			ConFileIndex itLie = m_PackFileIndex.begin();
			ConFileIndex itEnd = m_PackFileIndex.end();			
			for( ;itLie!=itEnd; ++itLie )
			{
				PACKAGE_INDEX pIndex = *(itLie->second);
				if( m_PackageHeader.btInfoSecIndex > 64 )
					ENCRYPT((BYTE *) pIndex.szFileName, 260, m_PackageHeader.secPassword[m_PackageHeader.btInfoSecIndex - 64 ], 888888, 16);
				if( _write( hFile, &pIndex, sizeof(pIndex) ) == -1 )
				{
					_chsize_s(hFile, m_PackageHeader.dwFileInfoOffset );
					m_PackageHeader.dwFileInfoOffset = 0;
					m_PackageHeader.dwFileInfoLength = 0;					
					break;
				}
			}
		}
	}



	_lseeki64(hFile, 0, SEEK_SET);
	SavePackageHeader(hFile);

	return m_PackageHeader.dwFileInfoOffset!=0;//
}
